package com.ecarx.vhaltests.hy11.testcases.system.vehicle;

import android.car.VehicleAreaType;
import android.car.VehiclePropertyIds;
import android.car.hardware.CarPropertyValue;
import android.car.hardware.property.CarPropertyManager;
import android.util.Log;

import androidx.test.platform.app.InstrumentationRegistry;

import com.ecarx.vhaltests.CallbackTimer;
import com.ecarx.vhaltests.IpcpClient;
import com.ecarx.vhaltests.VehicleConstants;
import com.ecarx.vhaltests.VhalUnitTestBase;
import com.ecarx.xui.adaptapi.car.IWrapper;

import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;

@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class HvacSteeringWheelHeatTest extends VhalUnitTestBase {
    static final Object lock = new Object();
    private static final String TAG = "HvacSteeringWheelHeatTest";
    private static final int HVAC_STEERING_WHEEL_HEAT = VehiclePropertyIds.HVAC_STEERING_WHEEL_HEAT;
    private static final int AUTO_STEERING_WHEEL_HEAT_LOW = 1;
    private static final int AUTO_STEERING_WHEEL_HEAT_MID = 2;
    private static final int AUTO_STEERING_WHEEL_HEAT_HIGH = 3;
    private static final int AUTO_STEERING_WHEEL_HEAT_OFF = 0;
    static IpcpClient ipcpClient;
    private static int halValue;
    private static int halStatus;
    private static int halArea;
    private boolean isFirstCbk;
    private CallbackTimer cbkTimer = new CallbackTimer();
    private CarPropertyManager.CarPropertyEventCallback callback;

    @BeforeClass
    public static void testInit() {
        setHvacSteeringWheelHeatAvail();
    }

    public static void setHvacSteeringWheelHeatAvail() {
        boolean isFirstSet = false;
        if (ipcpClient == null) {
            ipcpClient = new IpcpClient();
            isFirstSet = true;
        }
        int ccSvcId = 135;
        int ccOperId = 200;
        int[] configs = {186, 13};
        int[] values = {2, 4};
        int cemSvcId = 37;
        int cemOperId = 999;
        int[] cemOperIds = {999};
        int[] ccOperIds = {200};
        if (isFirstSet) {
            ipcpClient.setConfig(cemSvcId, cemOperIds);
            ipcpClient.setConfig(ccSvcId, ccOperIds);
        }
        // 设置CarConfig
        boolean resultCarConfig = ipcpClient.setCarconfigSignal(ccSvcId, ccOperId, configs, values);
        Assert.assertTrue(resultCarConfig);
        // 设置CEM
        String[] cems = {"vehModMngtGlbSafe1CarModSts1", "vehModMngtGlbSafe1UsgModSts", "steerWhlHeatgAvlSts"};
        int[] cemValues = {VehicleConstants.CAR_MODE_NOMAL, VehicleConstants.USG_MODE_CONVENIENCE, 1};
        boolean resultCEM = ipcpClient.setCEMSignal(cemSvcId, cemOperId, cems, cemValues);
        Assert.assertTrue(resultCEM);
        delay();
    }

    @Test
    public void test01_HvacSteeringWheelHeatNotAvail() {
        //反馈信号SteerWhlHeatgAvlSts 状态 导致NotActive
        setHvacSteeringWheelHeatStatsNotAvail();
        hvacSteeringWheelHeatAvailTest(false);
    }

    @Test
    public void test02_HvacSteeringWheelHeatNotAvail() {
        // CarConfig 状态导致 NotActive
        setHvacSteeringWheelHeatNotAvail();
        hvacSteeringWheelHeatAvailTest(false);
    }

    @Test
    public void test03_HvacSteeringWheelHeatAvail() {
        setHvacSteeringWheelHeatAvail();
        hvacSteeringWheelHeatAvailTest(true);
    }

    @Test
    public void test04_HvacSteeringWheelHeatSGet() {
        setHvacSteeringWheelHeatAvail();

        hvacSteeringWheelHeatGet(AUTO_STEERING_WHEEL_HEAT_LOW);

        hvacSteeringWheelHeatGet(AUTO_STEERING_WHEEL_HEAT_MID);

        hvacSteeringWheelHeatGet(AUTO_STEERING_WHEEL_HEAT_HIGH);

        hvacSteeringWheelHeatGet(AUTO_STEERING_WHEEL_HEAT_OFF);
    }

    @Test
    public void test05_HvacSteeringWheelHeatCallback() {
        setHvacSteeringWheelHeatAvail();
        isFirstCbk = true;
        Log.d(TAG, "test05_HvacSteeringWheelHeatCallback set HVAC_STEERING_WHEEL_HEAT value ：" + AUTO_STEERING_WHEEL_HEAT_LOW);
        mCarPropertyMgr.setIntProperty(HVAC_STEERING_WHEEL_HEAT, VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL, AUTO_STEERING_WHEEL_HEAT_LOW);
        delay(500);
        callback = new CarPropertyManager.CarPropertyEventCallback() {
            @Override
            public void onChangeEvent(CarPropertyValue carPropertyValue) {
                try {
                    if (isFirstCbk) {
                        isFirstCbk = false;
                    } else {
                        halValue = (int) carPropertyValue.getValue();
                        halStatus = carPropertyValue.getStatus();
                        halArea = carPropertyValue.getAreaId();
                        Log.d(TAG, "HVAC_STEERING_WHEEL_HEAT onChangeEvent value: propertyId ：" + carPropertyValue.getPropertyId() + " propertyValue：" + carPropertyValue.getValue() + "  status : " + carPropertyValue.getStatus());
                        Assert.assertEquals(halValue, AUTO_STEERING_WHEEL_HEAT_MID);
                        mCarPropertyMgr.unregisterCallback(callback);
                        cbkTimer.finish();
                    }
                } catch (Exception e) {
                    Log.e(TAG, e.getMessage());
                }
            }

            @Override
            public void onErrorEvent(int i, int i1) {
            }
        };
        mCarPropertyMgr.registerCallback(callback, HVAC_STEERING_WHEEL_HEAT, CarPropertyManager.SENSOR_RATE_ONCHANGE);
        mCarPropertyMgr.setIntProperty(HVAC_STEERING_WHEEL_HEAT, VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL, AUTO_STEERING_WHEEL_HEAT_MID);
        cbkTimer.start();
    }

    private void hvacSteeringWheelHeatAvailTest(boolean value) {
        boolean isAvail = mCarPropertyMgr.isPropertyAvailable(HVAC_STEERING_WHEEL_HEAT, VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL);
        Log.d(TAG, "HvacSteeringWheelHeatAvailTest  isAvail：" + isAvail);
        Assert.assertEquals(value, isAvail);
    }

    private void hvacSteeringWheelHeatGet(int value) {
        int bRet;
        Log.d(TAG, "HvacSteeringWheelHeatSet set HVAC_STEERING_WHEEL_HEAT value ：" + value);
        mCarPropertyMgr.setIntProperty(HVAC_STEERING_WHEEL_HEAT, VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL, value);
        delay();
        bRet = mCarPropertyMgr.getIntProperty(HVAC_STEERING_WHEEL_HEAT, VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL);
        Assert.assertEquals(value, bRet);
    }

    /**
     * 反馈信号SteerWhlHeatgAvlSts 状态 导致NotActive
     */
    public void setHvacSteeringWheelHeatStatsNotAvail() {
        // 设置CarConfig
        int ccSvcId = 135;
        int ccOperId = 200;
        int[] configs = {186, 13};
        int[] values = {2, 4};
        boolean resultCarConfig = ipcpClient.setCarconfigSignal(ccSvcId, ccOperId, configs, values);
        Assert.assertTrue(resultCarConfig);
        // 设置CEM
        int cemSvcId = 37;
        int cemOperId = 999;
        String[] cems = {"vehModMngtGlbSafe1CarModSts1", "vehModMngtGlbSafe1UsgModSts", "steerWhlHeatgAvlSts"};
        int[] cemValues = {VehicleConstants.CAR_MODE_NOMAL, VehicleConstants.USG_MODE_DRIVING, 3};
        boolean resultCEM = ipcpClient.setCEMSignal(cemSvcId, cemOperId, cems, cemValues);
        Assert.assertTrue(resultCEM);
        delay();
    }

    public void setHvacSteeringWheelHeatNotAvail() {
        // 设置CarConfig
        int ccSvcId = 135;
        int ccOperId = 200;
        int[] configs = {186, 13};
        int[] values = {3, 5};
        boolean resultCarConfig = ipcpClient.setCarconfigSignal(ccSvcId, ccOperId, configs, values);
        Assert.assertTrue(resultCarConfig);
        // 设置CEM
        int cemSvcId = 37;
        int cemOperId = 999;
        String[] cems = {"vehModMngtGlbSafe1CarModSts1", "vehModMngtGlbSafe1UsgModSts", "steerWhlHeatgAvlSts"};
        int[] cemValues = {VehicleConstants.CAR_MODE_NOMAL, VehicleConstants.USG_MODE_ABANDON, 1};
        boolean resultCEM = ipcpClient.setCEMSignal(cemSvcId, cemOperId, cems, cemValues);
        Assert.assertTrue(resultCEM);
        delay();
    }

}
